package com.lanou3g.code0510.reflection;

import java.lang.Object;

import java.io.OutputStream;

/**
 * Created by dllo on 18/5/10.
 */
public class Main {
    public static void main(String[] args) throws Exception {
        //反射是一种在程序运行期间,动态生效的技术,可以做到不使用硬编码
        /*
        反射三个最基本的操作:(反射的起始永远是为了获取类类型)
        1.创建对象(获取类类型)
        2.给属性赋值(通过反射操作属性)
        3.调用方法
         */
        //Person person = new Person();
        //反射创建
        //获取类类型的几种方式
        //第一种
        //通过类名获取类类型(类名.class)
        Class pClazz = Person.class;//此步骤为了获取类类型
        //1. Class类的类型就是Person这个类的类类型(即它含有Person这个类里的所有成员变量,属性,方法,类名);class为固定写法
        Object o = pClazz.newInstance();//pClazz拿到的是Person类里的属性,方法的信息
        //2. pClazz.newInstance();对象.方法,意思为调用对象的构造方法去创建实例,创建出的实例为Object类型(也可这么理解,
        //在创建出实例之前,Person类为一个空类,你拿不到它的类型,Person此时只是个空的名字)
        //3. 这个o对象,就会相当于是Person(此时Person类不为空)的一个对象,他会有Person的全部属性,我们就直接去使用o对象就可以了,也就避免了改源码
        //此时的Object就是Person类
        /*4. 为什么创建出来的实例类型为Object:因为它并不知道你要创建一个Person类,即Person类是在
        Object o = pClazz.newInstance();之后需要使用Person类时写出来的,所以在写前面的式子的
        时候,并不知道有Person这个类,所以pClazz.newInstance()拿不到Person类(即你要创建的类)的有效信息
        */
        //5. 这样写的意义:就是可以先写,就是我可以这个Object类,而这个Person类(只是个名字,没有含义),我没有确定,
        //o对象也就没有任何属性,但是当这个Person类有具体的类型的时候,比如他为动物类,人类或者物品类等等,那么这
        //个Object也就变成了相应的类,o也就有了相应的属性,我就可以直接对o进行一系列操作,而不需要new Person类
        /*6.例子:
        public static Object newInstance(Class claszz){
            try{
                Object o = clazz.newInstance();
                //对o一系列操作......
                return o;
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return null;
         }
         */
        //第二种
        //通过字符串获取类类型
        Class.forName("com.lanou3g.code0510.reflection.Person");
        //第三种
        //获取类类型,通过对象获取
        Person person = new Person();
        Class clazz3 = person.getClass();


        //2.给属性赋值
        //3.调用方法
    }
}
